using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Threading;
using NAudio.Wave;
using NAudio.CoreAudioApi;
using NAudio.Wave.SampleProviders;

namespace GameOverlayWPF
{
    /// <summary>
    /// 增强版音频播放服务 - 支持麦克风输出和音频混合
    /// </summary>
    public class EnhancedAudioService : IDisposable
    {
        private static EnhancedAudioService? _instance;
        public static EnhancedAudioService Instance => _instance ??= new EnhancedAudioService();

        private MediaPlayer? _mediaPlayer;
        private WasapiOut? _wasapiOut;
        private WasapiOut? _virtualOutput;
        private MixingSampleProvider? _mixer;
        private MMDevice? _defaultOutputDevice;
        private MMDevice? _virtualCableDevice;
        private bool _enableMicrophoneOutput = false;
        private float _volume = 0.8f;

        private EnhancedAudioService()
        {
            SetHighPriority();
            InitializeAudioDevices();
            
            // 在UI线程上初始化MediaPlayer作为备用
            System.Windows.Application.Current.Dispatcher.Invoke(() =>
            {
                _mediaPlayer = new MediaPlayer();
                _mediaPlayer.Volume = _volume;
                Debug.WriteLine("EnhancedAudioService initialized with NAudio and MediaPlayer");
            });
        }

        /// <summary>
        /// 初始化音频设备
        /// </summary>
        private void InitializeAudioDevices()
        {
            try
            {
                var enumerator = new MMDeviceEnumerator();
                
                // 获取默认输出设备（扬声器/耳机）
                _defaultOutputDevice = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
                Debug.WriteLine($"默认输出设备: {_defaultOutputDevice.FriendlyName}");
                
                // 查找虚拟音频线缆设备（常见名称）
                var allDevices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);
                _virtualCableDevice = allDevices.FirstOrDefault(d => 
                    d.FriendlyName.Contains("CABLE", StringComparison.OrdinalIgnoreCase) ||
                    d.FriendlyName.Contains("Virtual", StringComparison.OrdinalIgnoreCase) ||
                    d.FriendlyName.Contains("VB-Audio", StringComparison.OrdinalIgnoreCase) ||
                    d.FriendlyName.Contains("VAC", StringComparison.OrdinalIgnoreCase));
                
                if (_virtualCableDevice != null)
                {
                    Debug.WriteLine($"找到虚拟音频设备: {_virtualCableDevice.FriendlyName}");
                }
                else
                {
                    Debug.WriteLine("未找到虚拟音频设备，将只输出到默认设备");
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"初始化音频设备失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 设置是否启用麦克风输出模式
        /// </summary>
        public void EnableMicrophoneOutput(bool enable)
        {
            _enableMicrophoneOutput = enable;
            Debug.WriteLine($"麦克风输出模式: {(_enableMicrophoneOutput ? "已启用" : "已禁用")}");
        }

        /// <summary>
        /// 设置进程和线程为高优先级以确保音频播放不被中断
        /// </summary>
        private void SetHighPriority()
        {
            try
            {
                using (var currentProcess = Process.GetCurrentProcess())
                {
                    currentProcess.PriorityClass = ProcessPriorityClass.High;
                    Debug.WriteLine("进程优先级已设置为: High");
                }
                
                Thread.CurrentThread.Priority = ThreadPriority.Highest;
                Debug.WriteLine("线程优先级已设置为: Highest");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"设置高优先级失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 从嵌入资源中提取音频文件到临时文件
        /// </summary>
        private string? ExtractEmbeddedAudio(string resourceName)
        {
            try
            {
                var assembly = Assembly.GetExecutingAssembly();
                var fullResourceName = $"GameOverlayWPF.{resourceName}";
                
                Debug.WriteLine($"尝试提取嵌入资源: {fullResourceName}");
                
                using (var stream = assembly.GetManifestResourceStream(fullResourceName))
                {
                    if (stream == null)
                    {
                        Debug.WriteLine($"未找到嵌入资源: {fullResourceName}");
                        return null;
                    }
                    
                    var tempPath = Path.GetTempFileName();
                    var tempAudioPath = Path.ChangeExtension(tempPath, Path.GetExtension(resourceName));
                    File.Delete(tempPath);
                    
                    using (var fileStream = File.Create(tempAudioPath))
                    {
                        stream.CopyTo(fileStream);
                    }
                    
                    Debug.WriteLine($"嵌入资源已提取到: {tempAudioPath}");
                    return tempAudioPath;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"提取嵌入资源失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 使用NAudio播放音频，支持麦克风输出（优化版，解决断续问题）
        /// </summary>
        private async Task PlayWithNAudioAsync(string filePath)
        {
            await Task.Run(() =>
            {
                AudioFileReader? mainAudioFile = null;
                AudioFileReader? virtualAudioFile = null;
                
                try
                {
                    // 清理现有输出
                    _wasapiOut?.Stop();
                    _wasapiOut?.Dispose();
                    _virtualOutput?.Stop();
                    _virtualOutput?.Dispose();
                    _wasapiOut = null;
                    _virtualOutput = null;

                    // 读取音频文件
                    try
                    {
                        mainAudioFile = new AudioFileReader(filePath);
                    }
                    catch
                    {
                        // 如果NAudio无法读取，尝试使用MediaFoundation
                        var reader = new MediaFoundationReader(filePath);
                        mainAudioFile = new AudioFileReader(filePath);
                    }

                    // 设置音量
                    mainAudioFile.Volume = _volume;
                    
                    Debug.WriteLine($"音频格式: {mainAudioFile.WaveFormat.SampleRate}Hz, {mainAudioFile.WaveFormat.Channels}声道, {mainAudioFile.WaveFormat.BitsPerSample}位");

                    // 输出到默认设备（扬声器/耳机，让自己听到）
                    if (_defaultOutputDevice != null)
                    {
                        // 增加缓冲区到300ms，减少卡顿
                        _wasapiOut = new WasapiOut(_defaultOutputDevice, AudioClientShareMode.Shared, false, 300);
                        _wasapiOut.Init(mainAudioFile);
                        _wasapiOut.Play();
                        Debug.WriteLine("音频已输出到默认设备（缓冲：300ms）");
                    }

                    // 如果启用麦克风输出且存在虚拟设备，同时输出到虚拟设备
                    if (_enableMicrophoneOutput && _virtualCableDevice != null)
                    {
                        try
                        {
                            // 创建第二个AudioFileReader用于虚拟设备
                            virtualAudioFile = new AudioFileReader(filePath);
                            virtualAudioFile.Volume = _volume;
                            
                            // 获取虚拟设备的首选格式
                            var virtualDeviceFormat = _virtualCableDevice.AudioClient.MixFormat;
                            Debug.WriteLine($"虚拟设备格式: {virtualDeviceFormat.SampleRate}Hz, {virtualDeviceFormat.Channels}声道");
                            
                            // 创建重采样提供器以匹配虚拟设备格式
                            ISampleProvider sampleProvider = virtualAudioFile;
                            
                            // 如果采样率不匹配，进行重采样
                            if (virtualAudioFile.WaveFormat.SampleRate != virtualDeviceFormat.SampleRate)
                            {
                                var resampler = new MediaFoundationResampler(virtualAudioFile, virtualDeviceFormat.SampleRate);
                                sampleProvider = resampler.ToSampleProvider();
                                Debug.WriteLine($"音频重采样: {virtualAudioFile.WaveFormat.SampleRate}Hz -> {virtualDeviceFormat.SampleRate}Hz");
                            }
                            
                            // 增加缓冲区到300ms，与默认设备保持一致
                            _virtualOutput = new WasapiOut(_virtualCableDevice, AudioClientShareMode.Shared, false, 300);
                            
                            // 转换为Wave格式
                            var waveProvider = sampleProvider.ToWaveProvider();
                            _virtualOutput.Init(waveProvider);
                            
                            // 延迟一点再播放虚拟设备，确保同步
                            Thread.Sleep(10);
                            _virtualOutput.Play();
                            
                            Debug.WriteLine($"音频已同时输出到虚拟设备: {_virtualCableDevice.FriendlyName}（缓冲：300ms）");
                        }
                        catch (Exception virtualEx)
                        {
                            Debug.WriteLine($"虚拟设备输出失败: {virtualEx.Message}");
                            Debug.WriteLine("将继续播放到默认设备");
                        }
                    }
                    else if (_enableMicrophoneOutput && _virtualCableDevice == null)
                    {
                        Debug.WriteLine("警告: 麦克风输出模式已启用，但未找到虚拟音频设备");
                        Debug.WriteLine("请安装虚拟音频线缆（如 VB-Cable）以使用此功能");
                    }

                    // 等待播放完成（检查两个输出）
                    bool isPlaying = true;
                    while (isPlaying)
                    {
                        Thread.Sleep(50); // 减少检查间隔，更精确
                        
                        bool mainPlaying = _wasapiOut?.PlaybackState == PlaybackState.Playing;
                        bool virtualPlaying = _virtualOutput?.PlaybackState == PlaybackState.Playing;
                        
                        // 只要有一个还在播放就继续等待
                        isPlaying = mainPlaying || virtualPlaying;
                    }
                    
                    Debug.WriteLine("音频播放完成");
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"NAudio播放失败: {ex.Message}");
                    Debug.WriteLine($"错误详情: {ex.StackTrace}");
                    throw;
                }
                finally
                {
                    // 确保资源被正确清理
                    try
                    {
                        _wasapiOut?.Stop();
                        _wasapiOut?.Dispose();
                        _virtualOutput?.Stop();
                        _virtualOutput?.Dispose();
                        mainAudioFile?.Dispose();
                        virtualAudioFile?.Dispose();
                    }
                    catch (Exception cleanupEx)
                    {
                        Debug.WriteLine($"清理资源时出错: {cleanupEx.Message}");
                    }
                }
            });
        }

        /// <summary>
        /// 播放音频文件
        /// </summary>
        public async Task PlayAudioAsync(string filePath)
        {
            try
            {
                string actualFilePath = filePath;
                
                if (!File.Exists(filePath))
                {
                    Debug.WriteLine($"音频文件不存在: {filePath}");
                    
                    var fileName = Path.GetFileName(filePath);
                    Debug.WriteLine($"尝试从嵌入资源提取: {fileName}");
                    
                    var extractedPath = ExtractEmbeddedAudio(fileName);
                    if (extractedPath != null)
                    {
                        actualFilePath = extractedPath;
                        Debug.WriteLine($"成功从嵌入资源提取音频文件到: {actualFilePath}");
                    }
                    else
                    {
                        Debug.WriteLine("无法从嵌入资源提取音频文件");
                        return;
                    }
                }

                Debug.WriteLine($"尝试播放音频文件: {actualFilePath}");
                Debug.WriteLine($"麦克风输出模式: {(_enableMicrophoneOutput ? "已启用" : "已禁用")}");

                // 优先使用NAudio播放（支持麦克风输出）
                try
                {
                    await PlayWithNAudioAsync(actualFilePath);
                    Debug.WriteLine("音频播放成功（NAudio）");
                }
                catch (Exception naudioEx)
                {
                    Debug.WriteLine($"NAudio播放失败，尝试使用MediaPlayer: {naudioEx.Message}");
                    
                    // 降级到MediaPlayer（不支持麦克风输出）
                    await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
                    {
                        try
                        {
                            if (_mediaPlayer != null)
                            {
                                _mediaPlayer.Stop();
                                _mediaPlayer.Close();
                                
                                var uri = new Uri(actualFilePath, UriKind.Absolute);
                                _mediaPlayer.Open(uri);
                                
                                Task.Delay(50).ContinueWith(_ =>
                                {
                                    System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
                                    {
                                        _mediaPlayer.Play();
                                        Debug.WriteLine("MediaPlayer 播放命令已发送");
                                    }, DispatcherPriority.Send);
                                });
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine($"MediaPlayer 播放失败: {ex.Message}");
                        }
                    }, DispatcherPriority.Send);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"音频播放异常: {ex.Message}");
                Debug.WriteLine($"异常详情: {ex}");
            }
        }

        /// <summary>
        /// 游戏模式下播放音频（设置为最高优先级）
        /// </summary>
        public async Task PlayAudioInGameModeAsync(string filePath)
        {
            try
            {
                SetHighPriority();
                Debug.WriteLine("=== 游戏模式高优先级音频播放 ===");
                Thread.CurrentThread.Priority = ThreadPriority.Highest;
                
                await PlayAudioAsync(filePath);
                
                Debug.WriteLine("=== 游戏模式音频播放完成 ===");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"游戏模式音频播放失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 停止播放
        /// </summary>
        public void Stop()
        {
            try
            {
                _wasapiOut?.Stop();
                _virtualOutput?.Stop();
                
                if (_mediaPlayer != null)
                {
                    System.Windows.Application.Current.Dispatcher.Invoke(() =>
                    {
                        _mediaPlayer?.Stop();
                        Debug.WriteLine("音频播放已停止");
                    });
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"停止音频播放失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 设置音量
        /// </summary>
        public void SetVolume(double volume)
        {
            try
            {
                _volume = (float)Math.Max(0.0, Math.Min(1.0, volume));
                
                if (_mediaPlayer != null)
                {
                    System.Windows.Application.Current.Dispatcher.Invoke(() =>
                    {
                        _mediaPlayer.Volume = _volume;
                        Debug.WriteLine($"音量设置为: {_volume}");
                    });
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"设置音量失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 测试播放功能
        /// </summary>
        public void TestPlay(string filePath)
        {
            Debug.WriteLine($"高优先级测试播放: {filePath}");
            Debug.WriteLine($"文件是否存在: {File.Exists(filePath)}");
            if (File.Exists(filePath))
            {
                var fileInfo = new FileInfo(filePath);
                Debug.WriteLine($"文件大小: {fileInfo.Length} bytes");
                Debug.WriteLine($"文件扩展名: {fileInfo.Extension}");
            }
            
            Thread.CurrentThread.Priority = ThreadPriority.Highest;
            _ = PlayAudioAsync(filePath);
        }

        /// <summary>
        /// 列出可用的音频设备
        /// </summary>
        public void ListAudioDevices()
        {
            try
            {
                var enumerator = new MMDeviceEnumerator();
                Debug.WriteLine("\n=== 可用的音频输出设备 ===");
                
                foreach (var device in enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active))
                {
                    Debug.WriteLine($"设备: {device.FriendlyName}");
                    Debug.WriteLine($"  ID: {device.ID}");
                    Debug.WriteLine($"  状态: {device.State}");
                    Debug.WriteLine("");
                }
                
                Debug.WriteLine("=== 提示 ===");
                Debug.WriteLine("要启用麦克风输出功能，请安装虚拟音频线缆：");
                Debug.WriteLine("1. VB-Audio Virtual Cable (推荐): https://vb-audio.com/Cable/");
                Debug.WriteLine("2. 然后在语音软件中选择虚拟音频设备作为麦克风输入");
                Debug.WriteLine("3. 调用 EnableMicrophoneOutput(true) 启用此功能");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"列出音频设备失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            try
            {
                _wasapiOut?.Dispose();
                _virtualOutput?.Dispose();
                
                if (_mediaPlayer != null && System.Windows.Application.Current != null)
                {
                    System.Windows.Application.Current.Dispatcher.Invoke(() =>
                    {
                        _mediaPlayer?.Stop();
                        _mediaPlayer?.Close();
                        _mediaPlayer = null;
                        Debug.WriteLine("音频资源已释放");
                    });
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"释放音频资源失败: {ex.Message}");
            }
        }
    }
}
